Using the tangle exteriors, we can create branching sets of surgeries on the two knots K1 and K2. In this notebook, we verify these branching sets and build braid words of these that we can send to KnotJob and compute their Khovanov homologies from which we can read-off Watson's kappa invariant.

In [1]:
import snappy

def double_branched_cover(link):
    """
    Returns the double branched cover of the link.
    """
    L=link.copy()
    for i in range(L.num_cusps()):
        L.dehn_fill((2,0),i)
    for cov in L.covers(2):
        if (2.0, 0.0) not in cov.cusp_info('filling'):
            return cov
        
def all_positive(manifold):
    '''
    Checks if the solution type of a triangulation is positive.
    '''
    return manifold.solution_type() == 'all tetrahedra positively oriented'

def find_positive_triangulations(manifold,number=1,tries=100):
    '''
    Searches for one triangulation with a positive solution type.
    (Or if number is set to a different value also for different such triangulations.)
    '''
    M = manifold.copy()
    pos_triangulations=[]
    for i in range(tries):
        if all_positive(M):
            pos_triangulations.append(M)
            if len(pos_triangulations)==number:
                return pos_triangulations
            break
        M.randomize()
    for d in M.dual_curves(max_segments=500):
        X = M.drill(d)
        X = X.filled_triangulation()
        X.dehn_fill((1,0),-1)
        for i in range(tries):
            if all_positive(X):
                pos_triangulations.append(X)
                if len(pos_triangulations)==number:
                    return pos_triangulations
                break
            X.randomize()

    # In the closed case, here is another trick.
    if all(not c for c in M.cusp_info('is_complete')):
        for i in range(tries):
            # Drills out a random edge
            X = M.__class__(M.filled_triangulation())
            if all_positive(X):
                pos_triangulations.append(X)
                if len(pos_triangulations)==number:
                    return pos_triangulations
            break
            M.randomize()
    return pos_triangulations

def better_is_isometric_to(X,Y,return_isometries=False,index=100,try_hard=False):
    """
    Returns True if X and Y are isometric.
    Returns False if X and Y have different homologies.
     """ 
    if return_isometries==False:
        w='unclear'
        if X.homology()!=Y.homology():
            return False
        for i in (0,index):
            try:
                w=X.is_isometric_to(Y)
            except (RuntimeError,snappy.SnapPeaFatalError):
                pass
            if w==True:
                return w
            X.randomize()
            Y.randomize()
            i=i+1
        if try_hard:
            pos_triang_X=find_positive_triangulations(X,number=1,tries=index)
            pos_triang_Y=find_positive_triangulations(Y,number=1,tries=index)
            for X in pos_triang_X:
                for Y in pos_triang_Y:
                    w=better_is_isometric_to(X,Y,index=100,try_hard=False)
                    if w==True:
                        return w
        return 'unclear'
    if return_isometries==True:
        w=False
        if X.homology()!=Y.homology():
            return []
        for i in (0,index):
            try:
                w=X.is_isometric_to(Y,return_isometries)
            except (RuntimeError,snappy.SnapPeaFatalError):
                pass
            if w!=False:
                return w
            X.randomize()
            Y.randomize()
            i=i+1
        if try_hard:
            pos_triang_X=find_positive_triangulations(X,number=10,tries=index)
            pos_triang_Y=find_positive_triangulations(Y,number=10,tries=index)
            for X in pos_triang_X:
                for Y in pos_triang_Y:
                    w=better_is_isometric_to(X,Y,return_isometries,index=100,try_hard=False)
                    if w!=False:
                        return w
        return []
    
import regina

def to_regina(data):
    '''
    This function was written by Dunfield.
    It sends a SnapPy triangulation to regina.
    '''
    if hasattr(data, '_to_string'):
        data = data._to_string()
    if isinstance(data, str):
        if data.find('(') > -1:
            data = closed_isosigs(data)[0]
        return regina.Triangulation3(data)
    assert isinstance(data, regina.Triangulation3)
    return data

def display1(sig, tri):
    signatures1.append(sig)
    return False

def display2(sig, tri):
    signatures2.append(sig)
    return False

def search_for_combinatorial_equivalence(M,N,index_M=1,index_N=1):
    '''
    Takes as input two snappy triangulations, transforms them to regina and searches through the pachner graph for an 
    equivalence.
    '''
    F1=M.filled_triangulation()
    F2=N.filled_triangulation()
    T1=to_regina(F1)
    T2=to_regina(F2)
    T1.simplifyExhaustive()
    T2.simplifyExhaustive()
    global signatures1
    signatures1=[]
    global signatures2
    signatures2=[]
    T1.retriangulate(index_M,1,display1)
    T2.retriangulate(index_N,1,display2)
    for s1 in signatures1:
        for s2 in signatures2:
            if s1==s2:
                return True
    return False

import string

def braid_word_to_letters(word):
    '''Returns an alphabetical describtion of the braid word.'''
    upper=list(string.ascii_uppercase)
    lower=list(string.ascii_lowercase)
    stringword=''
    for x in word:
        for letter in lower:
            if x==ord(letter) - 96:
                stringword=stringword+letter
                break
        for letter in upper:
            if -x==ord(letter) - 64:
                stringword=stringword+letter
                break
    return stringword
In [2]:
branching_sets=[[['t09847','K8_201'],
[[(-22,1),[-1, 2, -3, -4, -5, 6, 5, -4, 3, -2, 4, 1, -3, 5, -6, -7, -6, -5, 4, -3, -2, -3, -4, 5, -4, 6, 3, 7, -4, -5, -5, -5, -5, -4, -3, 2]],             
[(-21,1),[-1, -2, 3, -4, -5, 6, 5, 7, -4, -6, -3, 5, 2, -4, 1, -3, -2, -4, -3, -5, 6, 5, -7, 4, -3, 5, 2, -4, -6, 3, -4, -5, -5, -5, -4]],
[(-20,1),[-1, 2, -3, -4, -5, 6, 5, -4, 3, -2, 4, 1, -3, 5, -6, -7, -6, -5, 4, -3, -2, -3, -4, 5, -4, 6, 3, 7, -4, -5, -5, -4, -3, 2]],
[(-19,1),[-1, 2, -3, -4, -3, 5, 4, -3, -2, 1, 3, 4, -5, -4, 6, -3, -5, 4, -3, 2, -3, -4, -3, 5, -2, -4, -6, 3]],
[(-18,1),[-1, -2, -2, -3, 4, -3, -2, 1, 3, 2, -3, -4, 5, 4, 4, -3, -2, 3, 4, -5]],
[(-17,1),[-1, 2, -3, -4, -5, -4, 3, -2, -4, 1, 3, 5, -4, 6, 5, 7, -4, 6, 3, -5, 2, 4, -3, -5, -4, 5, -6, -5, -7, -4, -6, 3, -2]], 
[(-16,1),[-1, 2, 3, -4, -3, 5, -6, 5, 4, -3, -2, 1, -3, 2, -3, -4, -4, -3, 4, 4, -5, 4, 6, -3, -2, -3, -4, -5, 4, 3, 3]], 
[(-15,1),[-1, 2, -3, -4, 5, -4, 6, -7, 6, -5, 4, 4, 3, -2, 4, 1, 5, -4, -6, 5, 7, -4, -8, 3, -7, 2, 6, -5, 4, -3, -5, -4, 5, -6, -5, 7, -4, -6, 8, 3, -5, -2, -4, 3]],  
[(-14,1),[-1, -2, -3, -4, 5, -4, 6, 3, 7, 2, -4, -8, 1, -3, -5, -7, 2, 4, -5, -6, -5, -4, -3, -4, 5, -4, 6, 3, 5, 7, -2, -4, -6, 8, -5, 4, 3, 4, 5, 4, 6, 4, -7, -5, -6, -5, -4]]]],
[['o9_30634', 'K9_449'],
[[(-18,1),[-1, 2, 3, -4, 5, -4, -3, -2, 4, 1, -3, -2, -4, -5, -4, 6, -3, 4, -3, -5, -3, -3, 4, 3, 3, 2, -3, 4, 5, 4, -6]], 
[(-17,1),[-1, 2, -3, 2, -4, 5, -4, 6, -4, -3, 4, -3, -5, -4, 3, -2, 1, 3, 4, -3, 5, 2, 4, -6, 4, -3, -5, 4, -3, -2]], 
[(-16,1),[-1, 2, -3, -4, -3, 5, -2, -6, 1, -3, 4, 3, -4, 3, 5, -4, 3, -2, 3, -4, -3, 4, -5, 4, 6, -5, 4, -3, 2]], 
[(-15,1),[-1, 2, 3, -4, 5, 6, 5, 4, -3, 5, -2, -6, 1, -3, 7, 4, -3, 5, 2, -4, 3, 5, -4, 6, 5, -4, -3, -2, 3, -4, -5, -6, -7]],  
[(-14,1),[-1, -2, -3, -4, -5, 4, -6, 5, -4, 3, 2, -4, 1, -3, 4, 4, -5, 4, 6, 3, -5, -2, 3, -4, 3, 5, 2]],  
[(-13,1),[-1, -2, 3, -2, -4, -3, 2, 1, 2, 2, -3, -2, 4, 3, -2, 3, 3, 3]],  
[(-12,1),[-1, -2, 3, -4, -5, -6, -5, -4, 3, 3, -2, 1, -3, -2, -3, 4, -3, 5, 2, 4, 6, -3, -5, -4, 5]],  
[(-11,1),[-1, 2, -3, 4, -3, -2, 1, -3, -2, -4, 5, 4, 6, 3, 4, 4, 4, 3, 5, -4, 3, 2, 3, -4, -3, 4, -5, 4, -6, -5]],  
[(-10,1),[-1, 2, -3, 4, 5, -6, -7, 8, -7, 9, 6, 10, -5, -4, 3, -5, -2, 4, 6, 1, 3, -5, -7, -8, -7, 9, 6, 8, -5, -4, -5, -6, -7, 6, -5, 4, -3, 2, -4, 3, -5, -4, 5, -6, 7, -8, 7, -9, -6, 8, -10, 5, 7, -9, 4, -8, -3, 7, -2, -6, -7]]]]] 
In [3]:
for data in branching_sets:
    K=snappy.Manifold(data[0][1])
    print('We consider the knot:',data[0][1],'=',data[0][0])
    for [slope,word] in data[1]:
        K.dehn_fill(slope)
        print(K)
        B=snappy.Link(braid_closure=word).exterior()
        D=double_branched_cover(B)
        #print(K.homology(),D.homology())
        w=better_is_isometric_to(K,D,try_hard=True)
        print('Branching set is verified via SnapPy:',w)
        if w=='unclear':
            v=search_for_combinatorial_equivalence(K,D,index_M=1,index_N=1)
            if v==False:
                v=search_for_combinatorial_equivalence(K,D,index_M=2,index_N=1)
            if v==False:
                v=search_for_combinatorial_equivalence(K,D,index_M=1,index_N=2)
            print('Branching set is verified via regina:',v)
    print('------')
We consider the knot: K8_201 = t09847
K8_201(-22,1)
Branching set is verified via SnapPy: True
K8_201(-21,1)
Branching set is verified via SnapPy: True
K8_201(-20,1)
Branching set is verified via SnapPy: True
K8_201(-19,1)
Branching set is verified via SnapPy: unclear
Branching set is verified via regina: True
K8_201(-18,1)
Branching set is verified via SnapPy: unclear
Branching set is verified via regina: True
K8_201(-17,1)
Branching set is verified via SnapPy: True
K8_201(-16,1)
Branching set is verified via SnapPy: True
K8_201(-15,1)
Branching set is verified via SnapPy: True
K8_201(-14,1)
Branching set is verified via SnapPy: True
------
We consider the knot: K9_449 = o9_30634
K9_449(-18,1)
Branching set is verified via SnapPy: True
K9_449(-17,1)
Branching set is verified via SnapPy: True
K9_449(-16,1)
Branching set is verified via SnapPy: True
K9_449(-15,1)
Branching set is verified via SnapPy: True
K9_449(-14,1)
Branching set is verified via SnapPy: unclear
Branching set is verified via regina: True
K9_449(-13,1)
Branching set is verified via SnapPy: True
K9_449(-12,1)
Branching set is verified via SnapPy: True
K9_449(-11,1)
Branching set is verified via SnapPy: True
K9_449(-10,1)
Branching set is verified via SnapPy: True
------

Next, we create alphabetical braid words.

In [4]:
for data in branching_sets:
    K=snappy.Manifold(data[0][1])
    #print(K)
    for [slope,word] in data[1]:
        print(slope,braid_word_to_letters(word))
    print('------')
(-22, 1) AbCDEfeDcBdaCeFGFEdCBCDeDfcgDEEEEDCb
(-21, 1) ABcDEfegDFCebDaCBDCEfeGdCebDFcDEEED
(-20, 1) AbCDEfeDcBdaCeFGFEdCBCDeDfcgDEEDCb
(-19, 1) AbCDCedCBacdEDfCEdCbCDCeBDFc
(-18, 1) ABBCdCBacbCDeddCBcdE
(-17, 1) AbCDEDcBDaceDfegDfcEbdCEDeFEGDFcB
(-16, 1) AbcDCeFedCBaCbCDDCddEdfCBCDEdcc
(-15, 1) AbCDeDfGfEddcBdaeDFegDHcGbfEdCEDeFEgDFhcEBDc
(-14, 1) ABCDeDfcgbDHaCEGbdEFEDCDeDfcegBDFhEdcdedfdGEFED
------
(-18, 1) AbcDeDCBdaCBDEDfCdCECCdccbCdedF
(-17, 1) AbCbDeDfDCdCEDcBacdCebdFdCEdCB
(-16, 1) AbCDCeBFaCdcDceDcBcDCdEdfEdCb
(-15, 1) AbcDefedCeBFaCgdCebDceDfeDCBcDEFG
(-14, 1) ABCDEdFeDcbDaCddEdfcEBcDceb
(-13, 1) ABcBDCbabbCBdcBccc
(-12, 1) ABcDEFEDccBaCBCdCebdfCEDe
(-11, 1) AbCdCBaCBDedfcdddceDcbcDCdEdFE
(-10, 1) AbCdeFGhGifjEDcEBdfacEGHGifhEDEFGfEdCbDcEDeFgHgIFhJegIdHCgBFG
------